import { isEmpty } from "lodash";
import React, { useState, useEffect, useRef } from "react";
import PropTypes from "prop-types";
import Input from "antd/lib/input";
import routeWithApiKeySession from "@/components/ApplicationArea/routeWithApiKeySession";
import PageHeader from "@/components/PageHeader";
import Parameters from "@/components/Parameters";
import DashboardGrid from "@/components/dashboards/DashboardGrid";
import Filters from "@/components/Filters";
import { Dashboard } from "@/services/dashboard";
import location from "@/services/location";
import routes from "@/services/routes";
import { RefreshButton } from "./components/DashboardHeader";
import useDashboard from "./hooks/useDashboard";
import ParticleWave from 'particle-wave';
// import { Fireworks } from 'fireworks-js/dist/react';
import Snowfall from 'react-snowfall';
import animate from 'bubbles-animation';

import "./PublicDashboardPage.less";
import "./components/DashboardHeader.less";

function PublicDashboard({ dashboard }) {
  const dashboardOptions = useDashboard(dashboard);
  const { globalParameters, filters, setFilters, setRefreshRate, refreshDashboard, loadWidget, refreshWidget } = dashboardOptions;
  const hideHeader = window.location.search.includes("hide_header");
  const hideParametersUI = window.location.search.includes("hide_parameters");

  //通过url参数设置样式
  if (dashboard.layout) {
    if (!!dashboard.layout.refresh && parseInt(dashboard.layout.refresh)>0 && !window.location.search.includes("refresh")) {
      setRefreshRate(parseInt(dashboard.layout.refresh));
      refreshDashboard();
      location.initUrlStyle(dashboard);
    } else if (dashboard.layout.colorStyleMode) {
      location.initUrlStyle(dashboard);
    } else {
      location.initUrlStyle();
    }  
  } else {
    location.initUrlStyle();
  }

  const showPortal = window.location.search.includes("show_portal") && localStorage.getItem("colorstyle_mode");
  const scale = dashboard.layout.isVerticalCompact && dashboard.layout.designHeight ? window.innerHeight/dashboard.layout.designHeight : 1;      
  const scaleX = dashboard.layout.isVerticalCompact && dashboard.layout.designWidth ? window.innerWidth/dashboard.layout.designWidth : 1;      
  const hideRefreshButton = dashboard.layout.isHideRefresh || false;
  const isTitleCenter = dashboard.layout.isTitleCenter || false;
  const titleFontSize = (dashboard.layout && dashboard.layout.titleFontSize === 0) ? 0 : dashboard.layout.titleFontSize || 20;
  const accessCode = dashboard.layout.isAccessCode ? dashboard.layout.accessCode : '';      
  const [userCode, setUserCode] = useState('');

  const cssStyle = {
    left: 0,
    top: 0,
    width: '100%',
    height: '100%',
    position: 'fixed',
    background: '#00000000',
    zIndex: -1,
  }

  // const fireworksOptions = {
  //   speed: 3
  // }

  const particleRef = useRef();
  const bubblesRef = useRef();

  useEffect(() => {
    if (showPortal && dashboard.layout.affect === "particle") {
      const pointSize = 3;
      new ParticleWave(particleRef.current, {
        uniforms: {
          size: { type: 'float', value: pointSize },
          field: { type: 'vec3', value: [0, 0, 0] },
          speed: { type: 'float', value: 7 }
        },
        onResize (w, h, dpi) {
          const position = []
          const color = []
          const width = 400 * (w / h)
          const depth = 300
          const height = 5
          const distance = 5
          for (let x = 0; x < width; x += distance) {
            for (let z = 0; z < depth; z += distance) {
              position.push(-width / 2 + x, -30, -depth / 2 + z)
              color.push(0, 1 - (x / width) * 1, 0.5 + x / width * 0.5, z / depth)
            }
          }
          if (this.uniforms) {
            this.uniforms.field = [width, height, depth]
            this.uniforms.size = (h / 400) * pointSize * dpi
          }
          if (this.buffers) {
            this.buffers.position = position
            this.buffers.color = color
          }
        }
      });
    }

    if (showPortal && dashboard.layout.affect === "bubbles") {
      const bubblesOptions = {
        quantity: 2,         
        interval: 3, 
        size: [5, 25], 
        color: { 
          R: [15, 240],
          G: [15, 240],
          B: [15, 240],
          A: 1
        }
      };
      if(bubblesRef.current) animate(bubblesRef.current, bubblesOptions);
    }
  }, [showPortal, dashboard.layout.affect]);
  return (accessCode && accessCode !== userCode) ? (
    <div className="container p-t-10 p-b-20" style={showPortal ? {textAlign: "center", background: "#00000000"} : {textAlign: "center"}}>
      <div>
        <br/>
        <h4>该报表已设置查看码，请输入：</h4>
        <Input style={{ width: 100 }} autoFocus onChange={e => setUserCode(e.target.value)} />
      </div>
    </div>
  ) : (
    <React.Fragment>
      {showPortal && dashboard.layout.affect === "particle" && <div ref={particleRef} style={cssStyle} />}      
      {/* {showPortal && dashboard.layout.affect === "fireworks" && <Fireworks options={fireworksOptions} style={cssStyle} />}       */}
      {showPortal && dashboard.layout.affect === "snowfall" && <Snowfall snowflakeCount={20} style={cssStyle} />}      
      {showPortal && dashboard.layout.affect === "bubbles" && <canvas ref={bubblesRef} style={cssStyle} />}      
      <div className={isTitleCenter ? "container p-t-5 p-b-20" : "container p-t-10 p-b-20"} style={showPortal ? {background: "#00000000"} : null}>
        {!hideHeader && (
          <div className="dashboard-header" style={{background: "#00000000"}}>      
            {(titleFontSize>0) && (
            <div className="title-with-tags">
              <PageHeader title={dashboard.name} center={isTitleCenter} fontSize={titleFontSize} scale={scale} scaleX={scaleX} />
            </div>
            )}
            {!hideRefreshButton && (
              <div className="dashboard-control" style={isTitleCenter ? {position: "absolute", right: 0, top: -5} : null}>
                <RefreshButton dashboardOptions={dashboardOptions} />
              </div>
            )}
          </div>
        )}
        {!hideParametersUI && !isEmpty(globalParameters) && (
          <div className={showPortal ? "m-b-10 p-5" : "m-b-10 p-5 bg-white tiled"} style={showPortal ? {background: "#00000000"} : null}>
          <Parameters parameters={globalParameters} onValuesChange={refreshDashboard} />
        </div>
      )}
        {!hideParametersUI && !isEmpty(filters) && (
          <div className={showPortal ? "m-b-10 p-5" : "m-b-10 p-5 bg-white tiled"} style={showPortal ? {background: "#00000000"} : null}>
          <Filters filters={filters} onChange={setFilters} />
        </div>
      )}
        <div id="dashboard-container" style={showPortal ? (hideHeader ? {marginTop: '10px'} : {marginTop: '15px'}) : {marginLeft: '10px', marginRight: '10px', marginTop: '15px'}}>
        <DashboardGrid
          dashboard={dashboard}
            dashboardOptions={dashboardOptions}
          widgets={dashboard.widgets}
          filters={filters}
          isEditing={false}
          isPublic
          onLoadWidget={loadWidget}
          onRefreshWidget={refreshWidget}
            widgetMargins={window.location.search.includes("widget_margins") ? parseInt(location.search.widget_margins) : -1}
            widgetRadius={window.location.search.includes("widget_radius") ? parseInt(location.search.widget_radius) : -1}
            widgetHidePopMenus={dashboard.layout && dashboard.layout.isFobidSaveAs}
        />
      </div>
    </div>
    </React.Fragment>
  );
}

PublicDashboard.propTypes = {
  dashboard: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
};

class PublicDashboardPage extends React.Component {
  static propTypes = {
    token: PropTypes.string.isRequired,
    onError: PropTypes.func,
  };

  static defaultProps = {
    onError: () => {},
  };

  state = {
    dashboard: null,
  };

  componentDidMount() {
    Dashboard.getByToken({ token: this.props.token })
      .then(dashboard => this.setState({ dashboard }))
      .catch(error => this.props.onError(error));
  }

  render() {
    const { dashboard } = this.state;

    return (
      <div className="public-dashboard-page">
        {dashboard && (<PublicDashboard dashboard={dashboard} />)}
      </div>
    );
  }
}

routes.register(
  "Dashboards.ViewShared",
  routeWithApiKeySession({
    path: "/public/dashboards/:token([^-]+)(-.*)?",
    render: pageProps => <PublicDashboardPage {...pageProps} />,
    getApiKey: currentRoute => currentRoute.routeParams.token,
  })
);
